{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

Chapter 2 - Introduction to Python

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will be using the Jupyter notebook for many activities this semester. Every notebook has an associated language called the \"kernel\". We will be using in the Python 3 kernel from the IPython project.\n", "\n", "For more information on how to use the notebook, please read the following (which is also a notebook written by a Bryn Mawr student):\n", "\n", "* https://athena.brynmawr.edu/jupyter/hub/dblank/public/Jupyter%20Notebook%20Users%20Manual.ipynb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python is a programming language that has been under development for over 25 years [1].\n", "\n", "This Chapter will not cover everything in Python. If you would like, please consider the following resources:\n", "\n", "**Getting Started with Python**:\n", "\n", "* https://www.codecademy.com/learn/python\n", "* http://docs.python-guide.org/en/latest/intro/learning/\n", "* https://learnpythonthehardway.org/book/\n", "* https://www.codementor.io/learn-python-online\n", "* https://websitesetup.org/python-cheat-sheet/\n", "\n", "**Learning Python in Notebooks**:\n", "\n", "* http://mbakker7.github.io/exploratory_computing_with_python/\n", "\n", "This is handy to always have available for reference:\n", "\n", "**Python Reference**:\n", "\n", "* https://docs.python.org/3.5/reference/\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1 Statements" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python is an [imperative language](https://en.wikipedia.org/wiki/Imperative_programming) based on [statements](https://en.wikipedia.org/wiki/Statement_(computer_science)). That is, programs in Python consists of lines composed of statements. A statement can be:\n", "\n", "* a single expression\n", "* an assignment\n", "* a function call\n", "* a function definition\n", "* a statement; statement" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.1 Expressions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Numbers\n", " * integers\n", " * floating-point\n", " * complex numbers\n", "* strings\n", "* boolean values\n", "* lists and dicts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.1.1 Numbers" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "-3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "1\n", "2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "3.14" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.1.2 Strings" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "'apple'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "\"apple\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the Out might not match exactly the In. In the above example, we used double-quotes but the representation of the string used single-quotes. Python will default to showing representations of values using single-quotes, if it can." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.1.3 Boolean Values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "True" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.1.4 Lists and Dicts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python has three very useful data structures built into the language:\n", "\n", "* dictionaries (hash tables): {}\n", "* lists: []\n", "* tuples: (item, ...)\n", "\n", "List is a mutable list of items. Tuple is a read-only data structure (immutable)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[1, 2, 3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "1, 2, 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "{\"apple\": \"a fruit\", \"banana\": \"an herb\", \"monkey\": \"a mammal\"}" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "{\"apple\": \"a fruit\", \"banana\": \"an herb\", \"monkey\": \"a mammal\"}[\"apple\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.2 Function Calls" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are two ways to call functions in Python:\n", "\n", "1. by pre-defined infix operator name\n", "2. by function name, followed by parentheses\n", "\n", "Infix operator name:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "1 + 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "abs(-1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "operator.add(1, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1.1.2.1 Print" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Evaluating and display result as an Out, versus evaluating and printing result (side-effect)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.3 Special Values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.4 Defining Functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def plus(a, b):\n", " return a + b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plus(3, 4)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def plus(a, b):\n", " a + b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plus(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What happened? All functions return *something*, even if you don't specify it. If you don't specify a return value, then it will default to returning `None`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "\"a\" + 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Sidebar 2-1: How to Read Python Error Messages

\n", "\n", "

\n", "Python error messages \n", "

\n", "TypeError: Can't convert 'int' object to str implicitly\n", "

\n", "\n", "

Above the error message is the \"traceback\" also called the \"call stack\". This is a representation of the sequence of procedure calls that lead to the error. If the procedure call originated from code from a file, the filename would be listed after the word \"File\" on each line. If the procedure call originated from a notebook cell, then the word \"ipython-input-#-HEX\".\n", "

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.2 Equality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2.1 ==" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "1 == 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2.2 is" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[] is []" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "list() is list()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "tuple() is tuple()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "57663463467 is 57663463467" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Advanced Topics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Zen of Python:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python evolves. But there are limits:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from __future__ import braces" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.1 Python Warts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* http://web.archive.org/web/20031002184114/www.amk.ca/python/writing/warts.html\n", "* \n", "* https://www.python.org/dev/peps/pep-3099/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.2 Scope of variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Is not always clear:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "y = 0\n", "for x in range(10):\n", " y = x" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[x for x in range(10, 20)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.3 Scope" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python follows the LEGB Rule (after https://www.amazon.com/dp/0596513984/):\n", "\n", "* L, Local: Names assigned in any way within a function (def or lambda)), and not declared global in that function.\n", "* E, Enclosing function locals: Name in the local scope of any and all enclosing functions (def or lambda), from inner to outer.\n", "* G, Global (module): Names assigned at the top-level of a module file, or declared global in a def within the file.\n", "* B, Built-in (Python): Names preassigned in the built-in names module : open, range, SyntaxError,..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x = 3\n", "def foo():\n", " x=4\n", " def bar():\n", " print(x) # Accesses x from foo's scope\n", " bar() # Prints 4\n", " x=5\n", " bar() # Prints 5" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "foo()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See [scope_resolution_legb_rule.ipynb](scope_resolution_legb_rule.ipynb) for some additional readings on scope." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.4 Generators" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def function():\n", " for i in range(10):\n", " yield i" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "function()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "for y in function():\n", " print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.5 Default arguments" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def do_something(a, b, c):\n", " return (a, b, c)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "do_something(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def do_something_else(a=1, b=2, c=3):\n", " return (a, b, c)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "do_something_else()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def some_function(start=[]):\n", " start.append(1)\n", " return start" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "result = some_function()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "result.append(2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "other_result = some_function()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "other_result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.2 List comprehension" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"List comprehension\" is the idea of writing some code inside of a list that will generate a list.\n", "\n", "Consider the following:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[x ** 2 for x in range(10)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "temp_list = []\n", "for x in range(10):\n", " temp_list.append(x ** 2)\n", "temp_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But list comprehension is much more concise." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.3 Plotting" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After the magic, we then need to import the matplotlib library:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python has many, many libraries. We will use a few over the course of the semester.\n", "\n", "To create a simple line plot, just give a list of y-values to the function plt.plot()." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plt.plot([5, 8, 2, 6, 1, 8, 2, 3, 4, 5, 6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But you should never create a plot that doesn't have labels on the x and y axises, and should always have a title. Read the documentation on matplotlib and add labels and a title to the plot above:\n", "\n", "http://matplotlib.org/api/pyplot_api.html\n", "\n", "Another commonly used library (especially with matplotlib is numpy). Often imported as:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.6 Closures" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Are functions that capture some of the local bindings to variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def return_a_closure():\n", " dict = {}\n", " def hidden(operator, value, other=None):\n", " if operator == \"add\":\n", " dict[value] = other\n", " else:\n", " return dict[value]\n", " return hidden" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "thing = return_a_closure()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "thing(\"add\", \"apple\", 42)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "thing(\"get\", \"apple\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "thing.dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Where is dict?\n", "\n", "See http://www.programiz.com/python-programming/closure for more examples." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

References

\n", "\n", "[1] https://en.wikipedia.org/wiki/History_of_Python" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }